<?php

/*
Plugin Name: ACCS Communication System
Version: .1
Plugin URI: https://code.google.com/p/rollins-capstone-project/
Description: ACCS Rollins Capstone Project
Author: 2012 Capstone Class
Author URI: http://rollins.edu
*/

/*

REFERENCED: 
- Williams, Brad; Richard, Ozh; Tadlock, Justin (2011-02-17). 
  Professional WordPress Plugin Development John Wiley and Sons. Kindle Edition.
- Active Directory Integration Plugin 
  http://wordpress.org/extend/plugins/active-directory-integration/
- Simple Pie 
  http://simplepie.org/wiki/setup/sample_page

*/

/*
        This library is free software; you can redistribute it and/or
        modify it under the terms of the GNU Lesser General Public
        License as published by the Free Software Foundation; either
        version 2.1 of the License, or (at your option) any later version.

        This library is distributed in the hope that it will be useful,
        but WITHOUT ANY WARRANTY; without even the implied warranty of
        MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
        Lesser General Public License for more details.
*/
 
if (!class_exists('ACCSCommunicationSystem')) {

//RSS FEED ADDITIONS
$siteurl = get_bloginfo('wpurl');
define('ACCS_CAT_SPEC_RSS_FOLDER', dirname(plugin_basename(__FILE__)));
define('ACCS_CAT_SPEC_RSS_URL', get_option('siteurl').'/wp-content/themes/' .get_current_theme() .'/images/');
$category_specific_rss_version = 1.4;

add_option('rss_category_1_name', 'All Topics');
add_option('rss_category_1_link', 'http://www.rollins.edu/news/news-rss.rss');
add_option('rss_widget_title_name', 'Category Specific RSS');
add_option('cat_rss_all_cat', '1');
add_option('cat_rss_show_post_count', '1');
add_option('cat_rss_show_image_on_left', '1');


define('ACCS_PLUGIN_NAME', 'All Campus Communication System (ACCS)');
define('ACCS_PLUGIN_DIR', 'accs1');

define('ACCS_LOG_DEBUG', 6);
define('ACCS_LOG_INFO',  5);
define('ACCS_LOG_NOTICE',4);
define('ACCS_LOG_WARN',  3);
define('ACCS_LOG_ERROR', 2);
define('ACCS_LOG_FATAL', 1);
define('ACCS_LOG_NONE',  0);

define('ACCS_PREFIX', 'ACCS_COMMUNICATION_SYSTEM_');
define('ACCS_ADI_MEMBEROF', 'adi_memberof');
define('ACCS_ADI_DESCIPTION', 'adi_description'); //For finding staff, faculty, student and alumni
define('ACCS_ADI_AUTHCODE', 'AD_Integration_bulkimport_authcode');
define('ACCS_SUBSCRIPTION_KEY', 'accs-category-subscription');
define('ACCS_AUDIENCE_KEY', 'accs-audience');
define('ACCS_DATE_1', 'accs-date-1');
define('ACCS_DATE_2', 'accs-date-2');
define('ACCS_DATE_3', 'accs-date-3');
define('ACCS_DATES', 'accs-dates');
define('ACCS_AD_AUDIENCE_MAP_KEY', 'accs-ad-audience-map');

//Including Notification Emails file to be run
include dirname(__FILE__) . '/accs-notification-email.php';
   
class ACCSCommunicationSystem
{


    private $_loglevel;
    private $_logfile;

    private $_notify_on_error = false;
    private $_notification_email = '';

    /**
     * put desc here.
     *
     * Notes:
     *   class constructor
     *   register hooks to specific actions
     */
    public function __construct() 
    {

        //Set Logging
        $this->_loglevel = ACCS_LOG_DEBUG;
        $this->_logfile = dirname(__FILE__).'/accs.log'; 

        //Site Setup Stuff
        add_action('wp_enqueue_scripts', array(&$this, 'register_jquery'));

        //Setup Custom Post Types
        add_action('init', array(&$this, 'register_post_type_announcement'));
        add_action('init', array(&$this, 'register_post_type_event'));
        add_action('init', array(&$this, 'register_post_type_promotion'));
        add_action('init', array(&$this, 'remove_post_post_type' ));
        add_action('wp_dashboard_setup', array(&$this, 'remove_dashboard_widgets' ));
        add_action('admin_menu',         array(&$this, 'remove_unused_menu_items' ));
        add_action('init', array(&$this, 'register_taxonomies'));
         
        //POST Stuff
        add_action('add_meta_boxes',    array(&$this, 'create_common_post_meta'));
        add_action('edit_page_form',  	array(&$this, 'save_common_post_meta'));       
        add_action('edit_post',         array(&$this, 'save_common_post_meta'));
        add_action('save_post',         array(&$this, 'save_common_post_meta'));
        add_action('publish_post',      array(&$this, 'save_common_post_meta'));   
        add_action('admin_menu',		'remove_post_widgets');
        //Hides the All Campus Required ability from non-admin
     	add_filter('list_terms_exclusions', array(&$this, 'accs_list_terms_exclusions'));
     	
     	//DASHBOARD UPDATES
     	add_action('wp_dashboard_setup', 'remove_dashboard_widgets');
     	add_action('wp_dashboard_setup', 'custom_right_now_dashboard');
		add_filter('admin_footer_text', 'modify_footer_admin');     
     
        //CRON SETUP
        add_action('admin_menu', array(&$this, 'options_menu'));
        add_action('accs_cron_hook', array(&$this, 'send_email'));

        //User Stuff
        $this->subscriptions_page();   
        add_action('user_register',     array(&$this, 'init_user'));
        add_action('updated_user_meta', array(&$this, 'update_user'), 10, 4);        
        
        //RSS
        add_action('do_feed_customfeed', 'create_accs_customfeed', 10, 1);
        add_filter('generate_rewrite_rules', 'custom_feed_rewrite');
        
        //Active Directory
        add_action('group_members',     array(&$this, 'accs_group_members'));

        //Load Plugin Settings
        $this->load_settings();
        
    } 

    function accs_jquery_scripts()
    {
    	wp_enqueue_script(
    		'custom-script',
    		get_template_directory_uri() . '/js/custom_script.js',
    		array('jquery')
    	);
    }

    private function get_rss_feed($url)
    {   
        // Make sure SimplePie is included. You may need to change this to match the location of simplepie.inc.
        require_once('includes/simplepie.inc');
 
        // We'll process this feed with all of the default options.
        $feed = new SimplePie();
 
        // Set which feed to process.
        $feed->set_feed_url($url);
 
        // Run SimplePie.
        $feed->init();

        return $feed;
    }

    public function register_jquery()
    {
        wp_deregister_script( 'jquery' );
        wp_register_script( 'jquery', 'http://ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js');

		wp_enqueue_script('jquery');
		wp_enqueue_script('jquery-ui-core');
		wp_enqueue_script('jquery-ui-datepicker',  '../wp-includes/js/jquery/ui/jquery.ui.datepicker.min.js', array('jquery','jquery-ui-core') );



        /*
        //wordpress loads these by default it seems
        <script type='text/javascript' src='http://localhost:8888/wp-admin/load-scripts.php?c=1&amp;
            load=
            admin-bar,
            hoverIntent,
            common,
            jquery-color,
            jquery-ui-core,
            jquery-ui-widget,
            jquery-ui-tabs,
            jquery-ui-mouse,
            jquery-ui-resizable,
            jquery-ui-draggable,
            jquery-ui-button,
            jquery-ui-position,
            jquery-ui-dialog
            &amp;ver=52f38ccb5f3aeb66a31dafa94d2c0efe'></script>
        */
    } 

    /*
     * Initialize plugin options/settings
     */
    private function init_settings() 
    {

        //This is the initial map that will be used to figure out 
        //how to map a user from their active directory information
        //to the appropriate audience
        $member_map = array(
            'EMS-Students' => 'student',
            'EMS-All_Faculty_and_Staff' => 'faculty',
            'HOLT' => 'holt',
            'CRUM' => 'crummer',
            'ART'  => 'ass',
            'STAFF' => 'staff',
            'FAC' => 'faculty'
         );

        //initial required categories
        $requiredCategories = array('All Campus Required');



        //Register Plugin Option Settings
        add_option(ACCS_PREFIX . 'MEMBER_MAP', $member_map);

        //TODO: do stuff with these settings??
        add_option(ACCS_PREFIX . 'NOTIFY_ON_ERROR', false);
        add_option(ACCS_PREFIX . 'NOTIFICATION_EMAIL', NULL);
        add_option(ACCS_PREFIX . 'USER_PROFILE_TITLE_PREFIX', 'Rollins ACCS');
        add_option(ACCS_PREFIX . 'REQUIRED_SUBSCRIPTION_CATEGORIES', $requiredCategories);
        

        //Email Settings
        add_option(ACCS_PREFIX . 'MAIL_DEBUG', 2);
        add_option(ACCS_PREFIX . 'MAIL_AUTH', true);
        add_option(ACCS_PREFIX . 'MAIL_SECURE', 'tls');
        add_option(ACCS_PREFIX . 'MAIL_HOST', '');
        add_option(ACCS_PREFIX . 'MAIL_PORT', 587);
        add_option(ACCS_PREFIX . 'MAIL_USERNAME', '');
        add_option(ACCS_PREFIX . 'MAIL_PASSWORD', '');
        add_option(ACCS_PREFIX . 'MAIL_FROM', 'donotreply@example.com');
        add_option(ACCS_PREFIX . 'MAIL_FROM_NAME', 'Do Not Reply');
        add_option(ACCS_PREFIX . 'MAIL_ALT_BODY', 'To view the message, please use an HTML compatible email viewer!');
    }

    /*
     * Register's plugin settings
     */
     private function register_settings() 
     {
        register_setting('ADI-server-settings', 'AD_Integration_domain_controllers');
        register_setting('ADI-server-settings', 'AD_Integration_port', array(&$this, 'sanitize_port'));
        
        //Active Directory to Audience Map
        register_setting('ACCS-audiencemap-settings', ACCS_PREFIX . 'MEMBER_MAP');

        //Email Server Settings
        register_setting('ACCS-email-settings', ACCS_PREFIX . 'MAIL_DEBUG', array(&$this, 'sanitize_email_debug'));
        register_setting('ACCS-email-settings', ACCS_PREFIX . 'MAIL_AUTH', array(&$this, 'sanitize_email_auth'));
        register_setting('ACCS-email-settings', ACCS_PREFIX . 'MAIL_SECURE', array(&$this, 'sanitize_email_secure'));
        register_setting('ACCS-email-settings', ACCS_PREFIX . 'MAIL_HOST', array(&$this, 'sanitize_email_host'));
        register_setting('ACCS-email-settings', ACCS_PREFIX . 'MAIL_PORT', array(&$this, 'sanitize_email_port'));
        register_setting('ACCS-email-settings', ACCS_PREFIX . 'MAIL_USERNAME', array(&$this, 'sanitize_email_username'));
        register_setting('ACCS-email-settings', ACCS_PREFIX . 'MAIL_PASSWORD', array(&$this, 'sanitize_email_password'));
        register_setting('ACCS-email-settings', ACCS_PREFIX . 'MAIL_FROM', array(&$this, 'sanitize_email_from'));
        register_setting('ACCS-email-settings', ACCS_PREFIX . 'MAIL_FROM_NAME');
        register_setting('ACCS-email-settings', ACCS_PREFIX . 'MAIL_ALT_BODY');

     }

    /*
     * TODO: comment goes here
     */
    public function load_settings()
    { 

        //AD to Audience Mapping
        $this->_membermap = get_option(ACCS_PREFIX . 'MEMBER_MAP');

        //TODO: do stuff with these settings??
        $this->_notify_on_error = get_option(ACCS_PREFIX . 'NOTIFY_ON_ERROR');
        $this->_notification_email = get_option(ACCS_PREFIX . 'NOTIFICATION_EMAIL');
        $this->_user_form_title_prefix = get_option(ACCS_PREFIX . 'USER_PROFILE_TITLE_PREFIX');
        $this->_required_subscription_categories = get_option(ACCS_PREFIX . 'REQUIRED_SUBSCRIPTION_CATEGORIES');

        //Email Settings
        $this->_email_debug     = get_option(ACCS_PREFIX . 'MAIL_DEBUG');
        $this->_email_auth      = get_option(ACCS_PREFIX . 'MAIL_AUTH');
        $this->_email_secure    = get_option(ACCS_PREFIX . 'MAIL_SECURE');
        $this->_email_host      = get_option(ACCS_PREFIX . 'MAIL_HOST');
        $this->_email_port      = get_option(ACCS_PREFIX . 'MAIL_PORT');
        $this->_email_username  = get_option(ACCS_PREFIX . 'MAIL_USERNAME');
        $this->_email_password  = get_option(ACCS_PREFIX . 'MAIL_PASSWORD');
        $this->_email_from      = get_option(ACCS_PREFIX . 'MAIL_FROM');
        $this->_email_from_name = get_option(ACCS_PREFIX . 'MAIL_FROM_NAME');
        $this->_email_alt_body  = get_option(ACCS_PREFIX . 'MAIL_ALT_BODY');

        //Load the bulk import authorization code
        $this->_adi_auth_code = get_option(ACCS_ADI_AUTHCODE);
    }

    /**
     * Saves the options to the sitewide options store. This is only needed for WPMU.
     * 
     * @param $arrPost the POST-Array with the new options
     * @return unknown_type
     */
    protected function save_settings($arrPost) {

         $this->accs_log_event(ACCS_LOG_DEBUG, 'Saving the settings!');

        if ( !empty($arrPost['accs_membermap_dict']))
            update_option(ACCS_PREFIX . 'MEMBER_MAP', 
                $this->sanitize_member_map($arrPost['accs_membermap_dict']));

        if ( !empty($arrPost['accs_email_debug']))
            update_option(ACCS_PREFIX . 'MAIL_DEBUG', 
                $this->sanitize_email_debug($arrPost['accs_email_debug']));

        if ( !empty($arrPost['accs_email_auth']))
            update_option(ACCS_PREFIX . 'MAIL_AUTH', 
                $this->sanitize_email_auth($arrPost['accs_email_auth']));

        if ( !empty($arrPost['accs_email_secure']))
            update_option(ACCS_PREFIX . 'MAIL_SECURE', 
                $this->sanitize_email_secure($arrPost['accs_email_secure']));

        if ( !empty($arrPost['accs_email_host']))
            update_option(ACCS_PREFIX . 'MAIL_HOST', 
                $this->sanitize_email_host($arrPost['accs_email_host']));

        if ( !empty($arrPost['accs_email_port']))
            update_option(ACCS_PREFIX . 'MAIL_PORT', 
                $this->sanitize_email_port($arrPost['accs_email_port']));

        if ( !empty($arrPost['accs_email_username']))
            update_option(ACCS_PREFIX . 'MAIL_USERNAME', 
                $this->sanitize_email_username($arrPost['accs_email_username']));

        if ( !empty($arrPost['accs_email_password']))
            update_option(ACCS_PREFIX . 'MAIL_PASSWORD', 
                $this->sanitize_email_port($arrPost['accs_email_password']));

        if ( !empty($arrPost['accs_email_from']))
            update_option(ACCS_PREFIX . 'MAIL_FROM', 
                $this->sanitize_email_from($arrPost['accs_email_from']));

        if ( !empty($arrPost['accs_email_from_name']))
            update_option(ACCS_PREFIX . 'MAIL_FROM_NAME', 
                $this->sanitize_email_from_name($arrPost['accs_email_from_name']));

        if ( !empty($arrPost['accs_email_alt_body']))
            update_option(ACCS_PREFIX . 'MAIL_ALT_BODY', 
                $this->sanitize_email_alt_body($arrPost['accs_email_alt_body']));
    }

    /*
     * TODO: comment goes here
     */
    private function sanitize_member_map($member_map) { 
        // $this->accs_log_event(ACCS_LOG_DEBUG, 'Entered Sanitize Member Map');
        $cnt = count($member_map);
        if ($cnt % 2 == 1){
            // $this->accs_log_event(ACCS_LOG_ERROR, 'Member Map was submitted by user that is not the right size. That is quite wrong.');
            wp_die('Member Map is not the right size. Things are quite wrong. Contact the system administrator.');
        }

        $new_map = array();
        $key = 'shouldNotBeAKey';

        //build a dictionary or map out of array
        foreach($member_map as $idx => $value){
            //handle key
            if($idx % 2 == 0){
                //This value is a key and must only exist once
                if (array_key_exists($value, $member_map)){
                    // $this->accs_log_event(ACCS_LOG_NOTICE, 'User tried to add identitical AD groups - bad ju ju');
                    wp_die('You can only list an AD Group once!');
                }
                $key = $value;
            }

            //handle value
            else {
                $new_map[$key] = $value;
            }
        }

        return $new_map; 
    }    

    /*
     * TODO: comment goes here
     */
    private function sanitize_email_debug($value)
    { return $value; }

    /*
     * TODO: comment goes here
     */
    private function sanitize_email_auth($value)
    { return trim($value); }

    /*
     * TODO: comment goes here
     */
    private function sanitize_email_secure($value)
    { return trim($value); }

    /*
     * TODO: comment goes here
     */
    private function sanitize_email_host($value)
    { return $value; }

    /*
     * TODO: comment goes here
     */
    private function sanitize_email_port($value)
    { return $value; }

    /*
     * TODO: comment goes here
     */
    private function sanitize_email_username($value)
    { return $value; }

    /*
     * TODO: comment goes here
     */
    private function sanitize_email_password($value)
    { return $value; }

    /*
     * TODO: comment goes here
     */
    private function sanitize_email_from($value)
    { return $value; }

    /*
     * TODO: comment goes here
     */
    private function sanitize_email_from_name($value)
    { return $value; }

    /*
     * TODO: comment goes here
     */
    private function sanitize_email_alt_body($value)
    { return $value; }

    /*
     * Return audience for user based on adi meta data
     */
    private function get_adi_user_audience($user_id)
    {

        //Example: memberof
        //CN=student180,OU=Groups,OU=WP,DC=Rollins,DC=edu
        //CN=EMS-Students,OU=Security Groups,OU=WP,DC=Rollins,DC=edu
        //CN=Domain Users,CN=Users,dc=Rollins,DC=edu

        //Load member map from plugin settings
        $member_map = get_option(ACCS_PREFIX . 'MEMBER_MAP');

        //Init audience array and get the ADI plugin data
        $audience = array();
        $info = get_user_meta($user_id, 'adi_memberof', true) . get_user_meta($user_id,'adi_description', true);
        
        //Build audience array
        if(!empty($info)){
            foreach($member_map as $ad_group => $accs_audience)
            {
                if (strpos($info, $ad_group) != false)
                    $audience[] = $accs_audience;                
            }
        }
        //return audience array
        return $audience;
    }

    /*
     * When a user is first created we should by default register
     * them for all categories.
     */
    public function init_user($user_id)
    {
        //query to get list of categories (even ones that have nothing in them)
        $args=array('orderby' => 'name','order' => 'ASC', 'hide_empty' => 0);
        $categories=get_categories($args);
        
        //build array of category names
        $categroy_names = array();
        foreach($categories as $cat)
        {
            if ($cat->name == 'Uncategorized')
                continue;
            $category_names[] = $cat->name;
        }        

        //store array of category names to user's subscription information        
        update_user_meta($user_id, ACCS_SUBSCRIPTION_KEY, $category_names, false);

        //call update_user for all the other usual updates
        $this->update_user(0, $user_id, 0, 0);
    }

    /*
     * When a user's information is updated - specifically we are worried about
     * the audience mapping be updated in the active directory plugin. When this
     * updates for a user we should read it and store it in a form that we can use
     */
    public function update_user($meta_id, $object_id, $meta_key, $_meta_value)
    {

        $user_id = $object_id; // MAYBE ... working theory

        //TODO: is it better to just update or should we check to see if anything has changed
        //before updating? TODO: go through the code for update_metadata and determine if check is already done

        $adi_audience = $this->get_adi_user_audience($user_id);

        //echo $user_id;

        // echo '<pre>';
        // print_r($adi_audience);
        // exit;

        //DEBUG
        $myFile = "debug.txt";
        $fh = fopen($myFile, 'w');
        foreach($adi_audience as $a){
            fwrite($fh, $a . '\n');
        }
        fwrite($fh, 'this thing ran\n');
        fclose($fh);
        //END DEBUG

        //$adi_audience = $this->get_adi_user_audience($user_id);        
        update_user_meta($user_id, ACCS_AUDIENCE_KEY, $adi_audience, false);
    
    }

    /**
     * Called when plugin is first activated from admin interface
     */
    public function activate() 
    {

        // register custom taxonomies
        $this->register_taxonomies();
        $this->populate_taxomies();
        
 		// register custom types
        $this->accs_register_new_capability();
        $this->register_post_type_announcement();
        $this->register_post_type_event();
        $this->register_post_type_promotion();
        $this->remove_post_post_type();
        //$this->remove_tag_taxonomy();
        $this->remove_unused_menu_items();
        $this->remove_dashboard_widgets();

        //Registr Plugin Settings
        $this->init_settings();
        
        //flush stuff
        flush_rewrite_rules();
        
        //create databases
        global $wpdb;
        global $accs_note_db_notes, $accs_note_db_generalnotes, $accs_notification_db_group, $accs_notification_db_collabrules, $accs_db_logs;
        
        $accs_notification_db_group = $wpdb->prefix . 'collaboration';
        $accs_notification_db_collabrules = $wpdb->prefix . 'collabrules';
        $accs_note_db_notes = $wpdb->prefix . 'collabnotes';
        $accs_note_db_generalnotes = $wpdb->prefix . 'generalnotes';
        $accs_db_logs = $wpdb->prefix . 'logs';

        //Create a table to log events
        if($wpdb->get_var('SHOW TABLES LIKE \'' . $accs_db_logs . '\'') != $accs_db_logs) {
            $sql = 'CREATE TABLE ' . $accs_db_logs . ' (
          log_id int(11) NOT NULL AUTO_INCREMENT,
  		  log_event varchar(20) NOT NULL,
  		  log_text text NOT NULL,
  		  log_timestamp datetime NOT NULL,
  			UNIQUE KEY log_id (log_id)
			);';

            $wpdb->query($sql);
        }
        
        
         // Add the table to hold group information and moderator rules
        if($wpdb->get_var('SHOW TABLES LIKE \'' . $accs_notification_db_group . '\'') != $accs_notification_db_group) {
            $sql = 'CREATE TABLE ' . $accs_notification_db_group . ' (
            collabgroup bigint(20) NOT NULL auto_increment,
            moderators longtext NOT NULL,
            groupname varchar(255) NOT NULL,
            KEY collabgroup (collabgroup)
            ) AUTO_INCREMENT=2;';

            $wpdb->query($sql);
        }      
        

        // Insert the default moderator rule
        $accs_moderator_check = $wpdb->get_var('SELECT moderators FROM ' . $accs_notification_db_group . ' WHERE collabgroup = 1');
        if ($accs_moderator_check == false)
        {
            $sql = 'INSERT INTO ' . $accs_notification_db_group . ' (collabgroup, moderators, groupname) VALUES 
            (1, \'a:1:{i:0;s:5:"admin";}\', \'Default\')';
            $wpdb->query($sql);
        }

        // Add the table to hold post type rules
        if( $wpdb->get_var( 'SHOW TABLES LIKE \'' . $accs_notification_db_collabrules . '\'' ) != $accs_notification_db_collabrules )
        {
            $sql = 'CREATE TABLE ' . $accs_notification_db_collabrules . ' (
                    rule_id int(11) NOT NULL auto_increment,
                    post_type varchar(50) NOT NULL,
                    taxonomy varchar(50) NOT NULL,
                    term varchar(255) NOT NULL,
                    moderators longtext NOT NULL,
                    UNIQUE KEY rule_id (rule_id)
                );';
            $wpdb->query( $sql );
        }

        // Add the table to hold post-specific notes
        if($wpdb->get_var('SHOW TABLES LIKE \'' . $accs_note_db_notes . '\'') != $accs_note_db_notes) {
            $sql = 'CREATE TABLE ' . $accs_note_db_notes . ' (
            `noteid` bigint(20) NOT NULL auto_increment,
            `postid` bigint(20) NOT NULL,
            `notecontent` text NOT NULL,
            `author` bigint(20) NOT NULL,
            `notetime` datetime NOT NULL,
            UNIQUE KEY `noteid` (noteid)
            ) AUTO_INCREMENT=1;';

            $added_notes_table = $wpdb->query($sql);
            if( $added_notes_table === 0 ) {
                $return .= '<p>Added notes table!</p>';
            }
        }

        // Add the table to hold general notes
        if($wpdb->get_var('SHOW TABLES LIKE \'' . $accs_note_db_generalnotes . '\'') != $accs_note_db_generalnotes) {
            $sql = 'CREATE TABLE ' . $accs_note_db_generalnotes . ' (
            `noteid` bigint(20) NOT NULL auto_increment,
            `notecontent` text NOT NULL,
            `author` bigint(20) NOT NULL,
            `notetime` datetime NOT NULL,
            `personal` BINARY NOT NULL DEFAULT \'1\',
            UNIQUE KEY `noteid` (noteid)
            ) AUTO_INCREMENT=1;';

            $added_generalnotes_table = $wpdb->query($sql);

            if( $added_generalnotes_table === 0 ) {
                $return .= '<p>Added general notes table!</p>';
            }
        }
    
    }

    /**
     * Called when plugin is deactivated from admin interface
     */
    public function deactivate() 
    {
        // un-register custom types

        // register custom taxonomies
        
    }

    /**
     * Called when plugin is uninstalled from admin interface
     */
    public function uninstall($echo=false) 
    {
       // if we had tables this is where we nuke em
        // remove custom post types?
        // remove custom taxonomies??

        //Unschedule Events
        $timestamp = wp_next_scheduled( 'accs_cron_hook' );
        wp_unschedule_event( $timestamp, 'accs_cron_hook' );
        
        //Remove notification tables
        global $wpdb;
        global $accs_note_db_notes, $accs_note_db_generalnotes, $accs_notification_db_group, $accs_notification_db_collabrules;

        if( $accs_note_db_notes == $wpdb->get_var('SHOW TABLES LIKE \'' . $accs_note_db_notes . '\'') )
        {
            $sql = 'DROP TABLE ' . $accs_note_db_notes;
            $wpdb->query($sql);
        }

        if( $accs_note_db_generalnotes == $wpdb->get_var('SHOW TABLES LIKE \'' . $accs_note_db_generalnotes . '\'') )
        {
            $sql = 'DROP TABLE ' . $accs_note_db_generalnotes;
            $wpdb->query($sql);
        }
        if($wpdb->get_var('SHOW TABLES LIKE \'' . $accs_notification_db_group . '\'') == $accs_notification_db_group) {
            $sql = 'DROP TABLE ' . $accs_notification_db_group;
            $wpdb->query($sql);
        }
        if($wpdb->get_var('SHOW TABLES LIKE \'' . $accs_notification_db_collabrules . '\'') == $accs_notification_db_collabrules) {
            $sql = 'DROP TABLE ' . $accs_notification_db_collabrules;
            $wpdb->query($sql);
        }
    }

    private function register_post_type($type, $labels, $supports, $taxonomies, $capabilities)
    {
        register_post_type($type, array(
            'labels' => $labels,
            'public' => true,
            'show_ui' => true,
            'publicly_queryable' => true,
            'exclude_from_search' => false,
            'has_archive' => true,
            'supports' => $supports,
            'taxonomies' => $taxonomies,
            //'capability_type' => $type,
            //'capabilities' => $capabilities,
            'menu_position' => 5,
        ));
    }

    public function register_post_type_announcement() 
    {
        $post_type = 'accs_announcement';
        $supports = array(
            'title',
            'editor',
            'thumbnail',
            'excerpt',
            'custom-fields',
            'revisions',
            'page-attributes'
        );
        $capabilities = array(
            'edit_post' => 'edit_accs_announcement',
            'edit_posts' => 'edit_accs_announcements',
            'edit_others_posts' => 'edit_others_accs_announcements',
            'publish_posts' => 'publish_accs_announcements',
            'read_post' => 'read_accs_announcement',
            'read_private_posts' => 'read_private_accs_announcements',
            'delete_post' => 'delete_accs_announcement',
        );
        $labels = array(
            'name' => __( 'Announcements' ),
            'singular_name' => __( 'Announcement' )
        );
        $taxonomies = array('category');

        $this->register_post_type($post_type, $labels, $supports, $taxonomies, $capabilities);
    }
	
	public function accs_register_new_capability(){
		$role = get_role('administrator');
		$role ->add_cap('see_special_cats');
	}


    public function register_post_type_event()
    {
        $post_type = 'accs_event';
        $supports = array(
            'title',
            'editor',
            'thumbnail',
            'excerpt',
            'custom-fields',
            'revisions',
            'page-attributes'
        );
        $capabilities = array(
            'edit_post' => 'edit_accs_event',
            'edit_posts' => 'edit_accs_events',
            'edit_others_posts' => 'edit_others_accs_events',
            'publish_posts' => 'publish_accs_events',
            'read_post' => 'read_accs_event',
            'read_private_posts' => 'read_private_accs_events',
            'delete_post' => 'delete_accs_event',
        );
        $labels = array(
            'name' => __( 'Events' ),
            'singular_name' => __( 'Event' )
        );
        $taxonomies = array('category');

        $this->register_post_type($post_type, $labels, $supports, $taxonomies, $capabilities);
    }

    public function register_post_type_promotion()
    {
        $post_type = 'accs_promo';
        $supports = array(
            'title',
            'editor',
            'thumbnail',
            'excerpt',
            'custom-fields',
            'revisions',
            'page-attributes'
        );
        $capabilities = array(
            'edit_post' => 'edit_accs_promo',
            'edit_posts' => 'edit_accs_promos',
            'edit_others_posts' => 'edit_others_accs_promos',
            'publish_posts' => 'publish_accs_promos',
            'read_post' => 'read_accs_promo',
            'read_private_posts' => 'read_private_accs_promos',
            'delete_post' => 'delete_accs_promo',
        );
        $labels = array(
            'name' => __( 'Promotions' ),
            'singular_name' => __( 'Promotion' )
        );
        $taxonomies = array('category');

        $this->register_post_type($post_type, $labels, $supports, $taxonomies, $capabilities);
    }

    public function create_common_post_meta()
    {
        //http://codex.wordpress.org/Function_Reference/add_meta_box
        //add_meta_box($id - html id, $title, $callback, $post_type, $context, $priority, $callback_args)
        add_meta_box('accs_custom_meta', 'Choose Announcement Dates', array(&$this, 'common_post_meta' ), 'accs_announcement');
        add_meta_box('accs_custom_meta', 'Choose Event Dates', array(&$this, 'common_post_meta' ), 'accs_event');
        add_meta_box('accs_custom_meta', 'Choose Promotion Dates', array(&$this, 'common_post_meta' ), 'accs_promo');
    }

    public function common_post_meta()
    {
        global $post;
        // Use nonce for verification
        wp_nonce_field( plugin_basename( __FILE__ ), 'accs_custom_post_meta_nonce' );
		$dates =  get_post_meta($post->ID, ACCS_DATES, true);
		
		if(count($dates) > 0){
			$d1 = mysql2date('D, M d, Y', $dates[0]) ;
	        $d2 = mysql2date('D, M d, Y', $dates[1]);
	        $d3 = mysql2date('D, M d, Y', $dates[2]);
        }
        else
        {
        	 $d1 = date("D, M d, Y");
        	 $d2 = date("D, M d, Y");
       		 $d3 = date("D, M d, Y");
        }		
		
        echo '<div class="accs_dates_meta"><ul>';

        // Date 1
        echo '<li><label for="accs_date1" style="padding-right:20px;"> First:</label>';
        echo '<input type="text" id="' .ACCS_DATE_1 .'" class="accs_dates" value="'.
            $d1.'" size="25"  name="' .ACCS_DATE_1 .'"/> </li>';

        // Date 2
        echo '<li><label for="accs_date2"> Second: </label>';
        echo '<input type="text" id="' .ACCS_DATE_2 .'" class="accs_dates" value="'.
            $d2.'" size="25"  name="' .ACCS_DATE_2 .'"/> </li>';

        // Date 3
        echo '<li><label for="accs_date3" style="padding-right:15px;"> Third:</label>';
        echo '<input type="text" id="' .ACCS_DATE_3 .'" class="accs_dates" value="'.
            $d3.'" size="25"  name="' .ACCS_DATE_3 .'"/> </li>';

        echo '</ul></div>';
        
        //TODO- PUT THIS IN enqueue and somewhere more useful. I could not get it to work right, so am hard coding it here for now -Sean
        $imageUrl =  get_bloginfo('template_url') . '/images/calendar.png';  
        
      	echo '
      		<link rel="stylesheet" href="../wp-content/themes/rollins_accs/jquery-ui-custom.css" />
      		<script src = "../wp-includes/js/jquery/ui/jquery.ui.datepicker.min.js"></script>
      		<script>  jQuery(document).ready(function($) {
				$(".accs_dates").datepicker({ dateFormat: "D, d M yy", minDate: 3, maxDate: 14, showOn:"both", buttonImage: "' .$imageUrl .'", buttonImageOnly: true });
   			});
   			</script>';   
   			//END TODO      
   	}

	//TODO- do we need the $post_id passed in? This is what I ssaw in the forums.
    public function save_common_post_meta( $post_id )
    {
        $edit_this = 'edit_' . $_POST['post_type']; 		
        // - still require nonce
        
        if (!wp_verify_nonce( $_POST['accs_custom_post_meta_nonce'], plugin_basename( __FILE__ )))
        	return;
         
       if('page' == $_POST['post_type'] ) 
  		{
    		if ( !current_user_can( 'edit_page', $post_id ) )
        		return;
        }
  		else
  		{
    		if ( !current_user_can($edit_this, $post_id ) && !current_user_can('edit_posts', $post_id ))
        		return;
  		}         
  		  		
        //TODO: do we require default values?
        $default = date('c');
        $d1 = isset($_POST[ACCS_DATE_1]) ? mysql2date('c', $_POST[ACCS_DATE_1]) : $default;
        $d2 = isset($_POST[ACCS_DATE_2]) ? mysql2date('c', $_POST[ACCS_DATE_2]) : $default;
        $d3 = isset($_POST[ACCS_DATE_3]) ? mysql2date('c', $_POST[ACCS_DATE_3]) : $default;
		$dates = array($d1, $d2, $d3);

        //TODO: MORE DATE VALIDATION!!!!?????
		update_post_meta($post_id, ACCS_DATES, $dates ); //Same format as posted when the EMS import occurs.       
    }

    /**
     * Removes the Post post_type from wordpress
     * 
     * @global type $wp_post_types //holds all current registered post types
     */
    public function remove_post_post_type()
    {
        global $wp_post_types;
        $post_type = 'post';
        if ( isset( $wp_post_types[$post_type] ))
            unset( $wp_post_types[$post_type]);
    }
    
    /**
     * Removes Menu items from the menu
     * 
     * @global type $menu //holds all currently displayed menu items
     */
    public function remove_unused_menu_items()
    {
        global $menu;
        $restricted = array(__('Posts')/*, __('Pages')*/);
        end ($menu);
        while (prev($menu)){
            $value = explode(' ',$menu[key($menu)][0]);
            if(in_array($value[0] != NULL?$value[0]:"" , $restricted))
                    unset($menu[key($menu)]);
        }
    }
    
    /**
     * Removes the Tag (post_tag) taxonomy from wordpress
     * 
     * @global type $wp_taxonomies //holds all currently used taxonomies in wordpress
     */
    public function remove_tag_taxonomy()
    {
	global $wp_taxonomies;
        $taxonomy = 'post_tag';
        if (taxonomy_exists( $taxonomy))
            unset( $wp_taxonomies[$taxonomy]);
    }
    
    /**
     * Removes the quickpress widget 
     */
    public function remove_dashboard_widgets()
    {
        remove_meta_box( 'dashboard_quick_press', 'dashboard', 'side' );
    }
    
    /**
     * Register custom taxonomy 
     */
    public function register_taxonomies()
    {
        register_taxonomy('audience'
            ,array('accs_event', 'accs_promo', 'accs_announcement', 'post')
            ,array(
                'hierarchical' => true,
                'label' => __( 'Audience' ),
                'sort' => true,
                'args' => array( 'orderby' => 'term_order' ),
                'rewrite' => array( 'slug' => 'audience' ),
            )
        );
    }

    /**
     * Populate taxonomy with custom data
     */
    function populate_taxomies()
    {
        if(!term_exists( 'faculty', 'audience' ))
        {
            wp_insert_term(
                'Faculty', // the term
                'audience', // the taxonomy
                array(
                    'description'=> 'Faculty',
                    'slug' => 'faculty'
                )
            );
        }

        if(!term_exists( 'student', 'audience' ))
        {
            wp_insert_term(
                'Student', // the term
                'audience', // the taxonomy
                array(
                    'description'=> 'Student',
                    'slug' => 'student',                    
                )
            );
        }

        if(!term_exists( 'alumni', 'audience' ))
        {
            wp_insert_term(
                'Alumni', // the term
                'audience', // the taxonomy
                array(
                    'description'=> 'Alumni',
                    'slug' => 'alumni'
                )
            );
        }   
        
        if(!term_exists( 'staff', 'audience' ))
        {
            wp_insert_term(
                'Staff', // the term
                'audience', // the taxonomy
                array(
                    'description'=> 'Staff',
                    'slug' => 'staff'
                )
            );
        }   

        if(!term_exists( 'a&s', 'audience' ))
        {
            wp_insert_term(
                'A&S', // the term
                'audience', // the taxonomy
                array(
                    'description'=> 'A&S',
                    'slug' => 'as'
                )
            );
        }   

        if(!term_exists( 'crummer', 'audience' ))
        {
            wp_insert_term(
                'Crummer', // the term
                'audience', // the taxonomy
                array(
                    'description'=> 'Crummer',
                    'slug' => 'crummer'
                )
            );
        }   

         if(!term_exists( 'holt', 'audience' ))
        {
            wp_insert_term(
                'Holt', // the term
                'audience', // the taxonomy
                array(
                    'description'=> 'Holt',
                    'slug' => 'holt'
                )
            );
        } 
        
         if(!term_exists( 'cpr', 'audience' ))
        {
            wp_insert_term(
                'CPS', // the term
                'audience', // the taxonomy
                array(
                    'description'=> 'CPS',
                    'slug' => 'cps'
                )
            );
        } 
        
        
        
         if(!term_exists( 'Academic Events', 'category' ))
        {
            wp_insert_term(
                'Academic Events', // the term
                'category', // the taxonomy
                array(
                    'description'=> 'Academic Events',
                    'slug' => 'academic-events'
                )
            );
        }   

        if(!term_exists( 'Arts, Culture, & Entertainment', 'category' ))
        {
            wp_insert_term(
                'Arts, Culture, & Entertainment', // the term
                'category', // the taxonomy
                array(
                    'description'=> 'Arts, Culture, & Entertainment',
                    'slug' => 'arts-culture-entertainment',
                    'count' => '1'
                )
            );
        }   

        if(!term_exists( 'Athletics, Sports, & Recreation', 'category' ))
        {
            wp_insert_term(
                'Athletics, Sports, & Recreation', // the term
                'category', // the taxonomy
                array(
                    'description'=> 'Athletics, Sports, & Recreation',
                    'slug' => 'athletics-sports-recreation'
                )
            );
        }   

        if(!term_exists( 'Community Service', 'category' ))
        {
            wp_insert_term(
                'Community Service', // the term
                'category', // the taxonomy
                array(
                    'description'=> 'Community Service',
                    'slug' => 'community-service'
                )
            );
        }   

        if(!term_exists( 'Co-op & Career Development', 'category' ))
        {
            wp_insert_term(
                'Co-op & Career Development', // the term
                'category', // the taxonomy
                array(
                    'description'=> 'Co-op & Career Development',
                    'slug' => 'co-op-career-development'
                )
            );
        }   

        if(!term_exists( 'Health & Wellness', 'category' ))
        {
            wp_insert_term(
                'Health & Wellness', // the term
                'category', // the taxonomy
                array(
                    'description'=> 'Health & Wellness',
                    'slug' => 'health-wellness'
                )
            );
        }   

        if(!term_exists( 'Meetings & Conferences', 'category' ))
        {
            wp_insert_term(
                'Meetings & Conferences', // the term
                'category', // the taxonomy
                array(
                    'description'=> 'Meetings & Conferences',
                    'slug' => 'meetings-conferences'
                )
            );
        }   

        if(!term_exists( 'Productivity & Development', 'category' ))
        {
            wp_insert_term(
                'Productivity & Development', // the term
                'category', // the taxonomy
                array(
                    'description'=> 'Productivity & Development',
                    'slug' => 'productivity-development'
                )
            );
        }   

        if(!term_exists( 'Special Events', 'category' ))
        {
            wp_insert_term(
                'Special Events', // the term
                'category', // the taxonomy
                array(
                    'description'=> 'Special Events',
                    'slug' => 'special-events'
                )
            );
        }   

        if(!term_exists( 'Student Life & Organizations', 'category' ))
        {
            wp_insert_term(
                'Student Life & Organizations', // the term
                'category', // the taxonomy
                array(
                    'description'=> 'Student Life & Organizations',
                    'slug' => 'student-life-organizations'
                )
            );
        }      
        
		if(!term_exists( 'All Campus Required', 'category' ))
        {
            wp_insert_term(
                'All Campus Required', // the term
                'category', // the taxonomy
                array(
                    'description'=> 'All Campus Required',
                    'slug' => 'all-campus-required'
                )
            );
        }        
    }

    /**
     *
     * Settings Menu
     * Defines a menu for the plugin settings 
     */
    public function options_menu()
    {
        //This creates a page that 
        add_options_page('ACCS Settings', 'ACCS Settings',
            'manage_options', 'accs-communication-system', array(&$this, 'display_options_page'));
    }

    /**
     *
     * User Subscriptions 
     * Defines a menu for the user subscription settings 
     */
    public function subscriptions_page()
    {
       include dirname(__FILE__) . '/accs-user-subscribe.php';
    }
    
    /**
     *
     * Settings Menu
     * Defines a menu for the plugin settings 
     */
    public function display_options_page()
    {
        include dirname(__FILE__) . '/accs-admin.php';
    }    
		
    /**
     *
     * CRON Settings for scheduling email
     * IMPORTANT NOTE: Cron only runs when site is visited. Need to have an 
     *   external service visit the website at scheduled time as well to ensure execution
     *   at the proper time.
     */
    public function cron_settings()
    {
        if (!wp_next_scheduled('accs_send_email'))
        {
            ////wp_schedule_event( timestamp, recurrence, hook, args );
            wp_schedule_event(time(), 'daily', 'accs_send_email');

        }
    }

	public function accs_log_event($key, $content)
	{
		if (!isset($wpdb))
		    $wpdb = new wpdb(DB_USER, DB_PASSWORD, DB_NAME, DB_HOST);
		
		$date = date("Y-d-j H:i:s");
		$wpdb->insert(
		    'wp_logs',
		    		array(
		    				'log_event' => $key,
		        			'log_text' => $content		        			
		    			 )
		  );	
	}

	
	function accs_list_terms_exclusions( $exclusions, $args=null ) {
  		global $pagenow;
 		$cats = implode(',', get_option(ACCS_PREFIX . 'REQUIRED_SUBSCRIPTION_CATEGORIES'));
 		if (in_array($pagenow,array('post.php','post-new.php')) && !current_user_can('see_special_cats')) {
    		$exclusions = " {$exclusions} AND t.name NOT IN ('" .$cats ."')";
  		}
 	 return $exclusions;
	}


}// end of class
} // end of class exists if


function wp_category_specific_rss_handler($atts)
{
    return show_cat_specific_rss_menu();
}

function show_cat_specific_rss_menu()
{
    $show_all_cat = get_option('cat_rss_all_cat');
    if ($show_all_cat == '1')
    {
            // Display Categories and RSS feed for all categories
            $output .= show_category_rss_for_all_cats();
    }
    else
    {
            $output .= show_specific_categories();

    }
    return $output;	
}


	function show_category_rss_for_all_cats()
	{		
		$rss_image = ACCS_CAT_SPEC_RSS_URL.'/rss_small_icon.png';
	
		$output = '<div id="cat_specific_rss">';
		if(get_option('cat_rss_show_image_on_left') == '1')
		{
			$output .= '<ul>';
			$customcats =  get_categories();
			foreach($customcats as $customcat)
			{
					if($customcat->name != 'Uncategorized'){
						$customcatlist .= '<li><a title="Subscribe to the '.$customcat->name.' feed" href="'.get_bloginfo('url').'/category/'.$customcat->slug.'/"><img src="'.$rss_image.'" alt="feed" /></a><a href="'.get_bloginfo('url').'/?feed=rss2&cat='.$customcat->term_id.'">'.$customcat->name.'</a></li>';
				}
			}
			$output .= $customcatlist;
			$output .= '</ul>';
		}
		else
		{
			$output .= '<ul>';		
			if(get_option('cat_rss_show_post_count') == '1')
			{
				$output .= wp_list_categories('orderby=name&show_count=1&feed_image='.$rss_image.'&title_li=');
			}
			else
			{
				$output .= wp_list_categories('orderby=name&feed_image='.$rss_image.'&title_li=');
			}		
			$output .= '</ul>';	
		}
		$output .= '</div>';	
		return $output;
	}


function create_accs_customfeed() {
		load_template( TEMPLATEPATH . '/accs_rss.php'); 
	}

	function custom_feed_rewrite($wp_rewrite) {
		$feed_rules = array(
		'feed/(.+)' => 'index.php?feed=' . $wp_rewrite->preg_index(1),
		'(.+).xml' => 'index.php?feed='. $wp_rewrite->preg_index(1)
		);
		$wp_rewrite->rules = $feed_rules + $wp_rewrite->rules;
		}

	

if( class_exists( 'ACCSCommunicationSystem' ) ) {
    $cn = new ACCSCommunicationSystem;
    // Register for activation
    register_activation_hook( __FILE__, array( &$cn, 'activate' ));
    register_deactivation_hook( __FILE__, array( &$cn, 'deactivate' ));
    register_uninstall_hook( __FILE__, array( &$cn, 'uninstall' ));
}